package com.marvels.financial.loan.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.marvels.approve.loan.dao.IMcamLoanApplyInfoDao;
import com.marvels.common.constants.*;
import com.marvels.common.dto.MarvelsResultDTO;
import com.marvels.common.dto.UserDTO;
import com.marvels.common.exception.MarvelsBusinessException;
import com.marvels.common.exception.MarvelsErrorCode;
import com.marvels.common.utils.CacheUtils;
import com.marvels.common.utils.DateUtils;
import com.marvels.common.utils.GenerateReqNoUtils;
import com.marvels.common.utils.MarvelsLogUtil;
import com.marvels.financial.consum.FinancialConsumerApproveApi;
import com.marvels.financial.loan.api.FinancialILoanAfterInfoApi;
import com.marvels.financial.loan.api.IProductInfoApi;
import com.marvels.financial.loan.dao.*;
import com.marvels.financial.loan.dto.*;
import com.marvels.financial.loan.service.ExtensionFunctionApi;
import com.marvels.financial.loan.service.ReplacePaymentApi;
import com.marvels.financial.loan.service.WithholdPaymentApi;
import com.marvels.loanapply.dao.AcLoanApplyInfoDao;
import com.marvels.loanapply.dto.AcLoanApplyInfoDTO;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

@Service
public class ReplacePaymentImpl implements ReplacePaymentApi {

	@Autowired
	private McfeLendingProcessDao mcfeLendingProcessDao;

	@Autowired
	private McfeWithholdCompensatoryDao compensatoryMapper;

	@Autowired
	private McfeRepaymentFlowDao mcfeRepaymentFlowDao;

	@Autowired
	private McfeWithholdCompensatoryLogDao logDao;

	@Autowired
	private FinancialConsumerApproveApi approveApi;

	@Autowired
	private FinancialILoanAfterInfoApi loanAfterInfoApi;

	@Autowired
	private McfeCustomerRepaymentPlanDao planDao;

	@Autowired
	private McfeRepaymentFlowDao flowDao;

	@Autowired
	private McfeReversalFlowDao reversalFlowDao;

	@Autowired
	private McfeCustomerLoanContractDao mcfeCustomerLoanContractDao;

	@Autowired
	private McfeCustomerRepaymentPlanDao mcfeCustomerRepaymentPlanDao;

	@Autowired
	private ExtensionFunctionApi extensionFunctionApi;

	@Autowired
	private WithholdPaymentApi withholdPaymentApi;

	@Autowired
	private OverDueManageMapper overDueManageMapper;

	@Autowired
	private McfeCustomerRepaymentPlanSellMapper mcfeCustomerRepaymentPlanSellMapper;

	@Autowired
	private McfeCustomerLoanContractSellMapper mcfeCustomerLoanContractSellMapper;

	@Autowired
	private IMcamLoanApplyInfoDao iMcamLoanApplyInfoDao;
	@Autowired
	private AcLoanApplyInfoDao acLoanApplyInfoDao;

	@Autowired
	private McfePaymentWithholdDetailDao detailDao;
	@Autowired
	private McfeRepaymentFlowDao repaymentFlowDao;
	@Autowired
	private IProductInfoApi iProductInfoApi;
	@Autowired
	private McfeReversalDetailDao reversalDetailDao;

	@Override
	public MarvelsResultDTO replacePaymentApplyInfo(ReplacePaymentConditionDto replacePaymentConditionDto)
			throws MarvelsBusinessException {
		int pageSize = replacePaymentConditionDto.getPageSize();
		int pageNum = replacePaymentConditionDto.getPageNum();
		if (pageSize < 1) {
			pageSize = PageConstant.PAGESIZE;
		}
		if (pageNum < 1) {
			pageNum = PageConstant.CURRPAGE;
		}
		PageHelper.startPage(pageNum, pageSize);

		Page<ReplacePaymentApplyInfo> list = null;
		//如果是采用分期模式查询应还款金额逻辑需特殊处理
		//if(StringUtils.equalsIgnoreCase("Y", CommonProperties.getNewRepaymentFlag())) {
			//list = mcfeCustomerLoanContractDao.newSelectContractReplace(replacePaymentConditionDto);
		//}else {
		list = mcfeCustomerLoanContractDao.selectContract(replacePaymentConditionDto);
		//}

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("list", list);
		map.put("total", list.getTotal());
		// 查询已拒绝份数,已经通过份数
		replacePaymentConditionDto.setPayType("1");
		ReplacePaymentAuditStatistics statistics = compensatoryMapper.selectStatistics(replacePaymentConditionDto);
		map.put("statistics", statistics);
		return MarvelsResultDTO.getResult(MarvelsErrorCode.SUCCESS.getValue(), "查询成功", map);
	}

	@Override
	public  void replacePaymentApply(ReplacePaymentConditionDto replacePaymentConditionDto)
			throws MarvelsBusinessException {
		//先判断代扣类别
//		String withholdCategory=replacePaymentConditionDto.getWithholdCategory();
//		if(StringUtils.isEmpty(withholdCategory)){
//			throw new MarvelsBusinessException("代扣类别不能为空");
//		}
//		if(withholdCategory.equals("1")){//扣还款金额
			paymentApply(replacePaymentConditionDto);
//		}else if(withholdCategory.equals("2")){
//			extensionApply(replacePaymentConditionDto);
//		}else{
//			throw new MarvelsBusinessException("代扣类别错误");
//		}

		return;
	}


	/**
	 * 展期申请
	 * @param replacePaymentConditionDto
	 * @throws MarvelsBusinessException
	 */
	public void extensionApply(ReplacePaymentConditionDto replacePaymentConditionDto) throws MarvelsBusinessException{
		if (StringUtils.isEmpty(replacePaymentConditionDto.getExtensionType())) {
			throw new MarvelsBusinessException("展期费类别不能为空");
		}
		String loanId = replacePaymentConditionDto.getLoanId();
		// 加锁 避免重复插入数据
		String key = RedisKeyConstant.HAND_PAYMENT_WITHHOLD + loanId;
		boolean isNotLock = false;
		try {
			isNotLock = CacheUtils.isNotLock(key, loanId);
			if (isNotLock) {
				// 先将这个key设置过期时间
				CacheUtils.setExpire(key, 60);
				List<ReplacePaymentApplyInfo> list = mcfeCustomerLoanContractDao.selectContract(replacePaymentConditionDto);
				if (list == null || list.size() < 1) {
					throw new MarvelsBusinessException("合同信息不存在");
				}
				// 判断进件是否处于还款状态
				if (list.get(0).getContractStatus().equals("2") || list.get(0).getContractStatus().equals("3")
						|| list.get(0).getContractStatus().equals("10")) {
					throw new MarvelsBusinessException("进件不处于还款状态");
				}
				McfeWithholdCompensatoryDto record = compensatoryMapper.selectCompensatory(
						replacePaymentConditionDto.getLoanId(), "1", replacePaymentConditionDto.getCustIdNumber(),"");
				// 查询审核流水表
				if (record != null && record.getStatus().equals("0")) {// 处于待审核状态
					throw new MarvelsBusinessException("已有申请正在审核中请稍候");
				}
				// 判断还款计划对应的进件是否有处在正在冲账中的流水
				McfeRepaymentFlowDTO flowDTO = flowDao.selectDealingByLoanId(replacePaymentConditionDto.getLoanId());
				if (flowDTO != null) {
					MarvelsLogUtil.getInstance()
							.info(">>>>>>>>>>loanId:" + replacePaymentConditionDto.getLoanId() + ",有处在冲账中或未冲账的流水");
					throw new MarvelsBusinessException("存在未冲账的流水,请稍候再试");
				}
				McfePaymentWithholdDetailDTO detailDTO = detailDao.selectTradingByLoanId(loanId);
				if (detailDTO != null) {
					MarvelsLogUtil.getInstance()
					.info(">>>>>>>>>>loanId:" + loanId + ",存在处理中的代扣");
					throw new MarvelsBusinessException("存在处理中的代扣请稍候再试");
				}
				UserDTO user = CacheUtils.getCacheUser();
				// 持久化审核申请信息
				record = new McfeWithholdCompensatoryDto();
				record.setCustCardNo(list.get(0).getCustCardNo());
				record.setCustName(replacePaymentConditionDto.getTransferUserName());
				record.setLoanId(list.get(0).getLoanId());
				record.setMobile(list.get(0).getCustMobile());
				record.setPaymentWay(replacePaymentConditionDto.getPaymentWay());
				record.setStatus("0");// 0:待审核，1:通过，2：拒绝
				record.setCreatedDate(new Date());
				record.setUpdatedDate(new Date());
				record.setPayType("1");// 还款类型: 1-代还款;2-代提前结清;3-代偿;4-代偿提前结清
				record.setCreatedBy(user.getUserName());
				record.setUpdatedDate(new Date());
				record.setTradeSerialNumber(replacePaymentConditionDto.getTradeSerialNumber());
				record.setRemarks(replacePaymentConditionDto.getRemarks());
				record.setPaymentWay(replacePaymentConditionDto.getPaymentWay());// 还款方式  1对公转账  2支付宝转账
				record.setUpdatedBy(user.getUserName());
				record.setWithholdCategory("2");//扣款类别 1 扣还款计划金额  2 扣展期费

				//查询展费信息
				ExtensionFunctionConditionDTO dto=new ExtensionFunctionConditionDTO();
				dto.setLoanId(loanId);
				dto.setType(replacePaymentConditionDto.getExtensionType());
				dto=extensionFunctionApi.selectExtensionInfo(dto);
				record.setExtensionDay(dto.getDay());
				record.setAmount(dto.getAmount());

				int count = compensatoryMapper.insertSelective(record);
				if (count < 1) {
					throw new MarvelsBusinessException("持久化审核申请信息失败");
				}
				// 记录申请流水
				try {
					McfeWithholdCompensatoryLogDto logDto = new McfeWithholdCompensatoryLogDto();
					logDto.setAmount(record.getAmount());
					logDto.setCustCardNo(list.get(0).getCustCardNo());
					logDto.setCustName(replacePaymentConditionDto.getTransferUserName());
					logDto.setLoanId(list.get(0).getLoanId());
					logDto.setMobile(list.get(0).getCustMobile());
					logDto.setStatus("0");// 0:待审核，1:通过，2：拒绝
					logDto.setCreatedDate(new Date());
					logDto.setUpdatedDate(new Date());
					logDto.setPayType("1");// 还款类型: 1-代还款;2-代提前结清;3-代偿;4-代偿提前结清
					logDto.setCreatedBy(user.getUserName());
					logDto.setUpdatedDate(new Date());
					logDto.setUpdatedBy(user.getUserName());
					logDto.setRemarks("代扣展期费审核申请");
					logDto.setWithholdCategory("2");//扣款类别 1 扣还款计划金额  2 扣展期费
					logDao.insertSelective(logDto);
				} catch (Exception e) {
					MarvelsLogUtil.getInstance().error(">>>>记录代还款审核申请异常:", e);
				}
			}
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error(">>>>>loanId:" + loanId + ",代还款申请异常:", e);
			throw new MarvelsBusinessException(e.getMessage());
		} finally {
			if (!CacheUtils.isNotLock(key, loanId)) {// 如果是锁住的将所释放
				CacheUtils.del(key);
			}
		}
	}



	/**
	 * 待还款申请
	 * @param replacePaymentConditionDto
	 * @throws MarvelsBusinessException
	 */
	public void paymentApply(ReplacePaymentConditionDto replacePaymentConditionDto) throws MarvelsBusinessException{
		// 先判断金额
		if (StringUtils.isEmpty(replacePaymentConditionDto.getPaymentAmountAct())) {
			throw new MarvelsBusinessException("实还金额不能为空");
		}
		if (StringUtils.isEmpty(replacePaymentConditionDto.getPaymentWay())) {
			throw new MarvelsBusinessException("还款方式不能为空");
		}
		if (StringUtils.isEmpty(replacePaymentConditionDto.getTransferUserName())) {
			throw new MarvelsBusinessException("转账人姓名不能为空");
		}
		if (StringUtils.isEmpty(replacePaymentConditionDto.getTradeSerialNumber())) {
			throw new MarvelsBusinessException("代扣流水号不能为空");
		}
		String loanId = replacePaymentConditionDto.getLoanId();
		// 加锁 避免重复插入数据
		String key = RedisKeyConstant.HAND_PAYMENT_WITHHOLD + loanId;
		boolean isNotLock = false;
		try {
			isNotLock = CacheUtils.isNotLock(key, loanId);
			if (isNotLock) {
				// 先将这个key设置过期时间
				CacheUtils.setExpire(key, 60);
				List<ReplacePaymentApplyInfo> list = mcfeCustomerLoanContractDao.selectContract(replacePaymentConditionDto);
				if (list == null || list.size() < 1) {
					throw new MarvelsBusinessException("合同信息不存在");
				}
				// 判断进件是否处于还款状态
				if (list.get(0).getContractStatus().equals("2") || list.get(0).getContractStatus().equals("3")
						|| list.get(0).getContractStatus().equals("10")) {
					throw new MarvelsBusinessException("进件不处于还款状态");
				}
				McfeWithholdCompensatoryDto record = compensatoryMapper.selectCompensatory(
						replacePaymentConditionDto.getLoanId(), "1", replacePaymentConditionDto.getCustIdNumber(),"");
				// 查询审核流水表
				if (record != null && record.getStatus().equals("0")) {// 处于待审核状态
					throw new MarvelsBusinessException("已有申请正在审核中请稍候");
				}
				// 判断还款计划对应的进件是否有处在正在冲账中的流水
				McfeRepaymentFlowDTO flowDTO = flowDao.selectDealingByLoanId(replacePaymentConditionDto.getLoanId());
				if (flowDTO != null) {
					MarvelsLogUtil.getInstance()
							.info(">>>>>>>>>>loanId:" + replacePaymentConditionDto.getLoanId() + ",有处在冲账中或未冲账的流水");
					throw new MarvelsBusinessException("存在未冲账的流水,请稍候再试");
				}
				McfePaymentWithholdDetailDTO detailDTO = detailDao.selectTradingByLoanId(loanId);
				if (detailDTO != null) {
					MarvelsLogUtil.getInstance()
					.info(">>>>>>>>>>loanId:" + loanId + ",存在处理中的代扣");
					throw new MarvelsBusinessException("存在处理中的代扣请稍候再试");
				}
				UserDTO user = CacheUtils.getCacheUser();
				// 持久化审核申请信息
				record = new McfeWithholdCompensatoryDto();
				BigDecimal auditAmount = new BigDecimal(replacePaymentConditionDto.getPaymentAmountAct()).setScale(2,
						BigDecimal.ROUND_HALF_DOWN);
				record.setAmount(auditAmount);
				record.setCustCardNo(list.get(0).getCustCardNo());
				record.setCustName(replacePaymentConditionDto.getTransferUserName());
				record.setLoanId(list.get(0).getLoanId());
				record.setMobile(list.get(0).getCustMobile());
				record.setPaymentWay(replacePaymentConditionDto.getPaymentWay());
				record.setStatus("0");// 0:待审核，1:通过，2：拒绝
				record.setCreatedDate(new Date());
				record.setUpdatedDate(new Date());
				record.setPayType("1");// 还款类型: 1-代还款;2-代提前结清;3-代偿;4-代偿提前结清
				record.setCreatedBy(user.getUserName());
				record.setUpdatedDate(new Date());
				String reqNo = GenerateReqNoUtils.transctionReq("DH");
				record.setTransctionSeq(reqNo);
				record.setTradeSerialNumber(replacePaymentConditionDto.getTradeSerialNumber());
				record.setRemarks(replacePaymentConditionDto.getRemarks());
				record.setPaymentWay(replacePaymentConditionDto.getPaymentWay());// 还款方式  1对公转账  2支付宝转账
				record.setUpdatedBy(user.getUserName());
				record.setWithholdCategory("1");//扣款类别 1 扣还款计划金额  2 扣展期费
				int count = compensatoryMapper.insertSelective(record);
				if (count < 1) {
					throw new MarvelsBusinessException("持久化审核申请信息失败");
				}
				// 记录申请流水
				try {
					McfeWithholdCompensatoryLogDto logDto = new McfeWithholdCompensatoryLogDto();
					logDto.setAmount(new BigDecimal(replacePaymentConditionDto.getPaymentAmountAct()));
					logDto.setCustCardNo(list.get(0).getCustCardNo());
					logDto.setCustName(replacePaymentConditionDto.getTransferUserName());
					logDto.setLoanId(list.get(0).getLoanId());
					logDto.setMobile(list.get(0).getCustMobile());
					logDto.setStatus("0");// 0:待审核，1:通过，2：拒绝
					logDto.setCreatedDate(new Date());
					logDto.setUpdatedDate(new Date());
					logDto.setPayType("1");// 还款类型: 1-代还款;2-代提前结清;3-代偿;4-代偿提前结清
					logDto.setCreatedBy(user.getUserName());
					logDto.setUpdatedDate(new Date());
					logDto.setUpdatedBy(user.getUserName());
					logDto.setRemarks("代还款审核申请");
					logDto.setWithholdCategory(replacePaymentConditionDto.getWithholdCategory());
					logDao.insertSelective(logDto);
				} catch (Exception e) {
					MarvelsLogUtil.getInstance().error(">>>>记录代还款审核申请异常:", e);
				}
			}
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error(">>>>>loanId:" + loanId + ",代还款申请异常:", e);
			throw new MarvelsBusinessException(e.getMessage());
		} finally {
			if (!CacheUtils.isNotLock(key, loanId)) {// 如果是锁住的将所释放
				CacheUtils.del(key);
			}
		}
	}

	@Override
	public Page<ReplacePaymentApplyInfo> replacePaymentAuditList(ReplacePaymentConditionDto replacePaymentConditionDto)
			throws MarvelsBusinessException {
		int pageSize = replacePaymentConditionDto.getPageSize();
		int pageNum = replacePaymentConditionDto.getPageNum();
		if (pageSize < 1) {
			pageSize = PageConstant.PAGESIZE;
		}
		if (pageNum < 1) {
			pageNum = PageConstant.CURRPAGE;
		}
		PageHelper.startPage(pageNum, pageSize);
		replacePaymentConditionDto.setPayType("1");// 还款类型: 1-代还款;2-代提前结清;3-代偿;4-代偿提前结清
		replacePaymentConditionDto.setAuditStatus("0");//0:待审核，1:通过，2：拒绝
		return compensatoryMapper.selectAllData(replacePaymentConditionDto);
	}

	@Override
	@Transactional(rollbackFor=Exception.class)
	public  void replacePaymentAuditAdopt(ReplacePaymentConditionDto replacePaymentConditionDto)
			throws MarvelsBusinessException {
		String withholdCategory=replacePaymentConditionDto.getWithholdCategory();
		if(StringUtils.isEmpty(withholdCategory)){
			throw new MarvelsBusinessException("代扣类别不能为空");
		}
//		if(withholdCategory.equals("1")){//扣还款金额
//			if (StringUtils.isEmpty(replacePaymentConditionDto.getPaymentWay()) ) {
//				throw new MarvelsBusinessException("请选择还款方式");
//			}
//			if (StringUtils.isEmpty(replacePaymentConditionDto.getPaymentAmountAct())) {
//				throw new MarvelsBusinessException("请输入实还金额");
//			}
//		}
		String loanId = replacePaymentConditionDto.getLoanId();
		// 加锁 避免重复插入数据
		String key = RedisKeyConstant.HAND_PAYMENT_WITHHOLD + loanId;
		boolean isNotLock = false;
		try {
			isNotLock = CacheUtils.isNotLock(key, loanId);
			if (isNotLock) {
				// 先将这个key设置过期时间
				CacheUtils.setExpire(key, 60);
				// 查询审核流水表
				McfeWithholdCompensatoryDto record = compensatoryMapper.selectCompensatory(
						replacePaymentConditionDto.getLoanId(), "1", replacePaymentConditionDto.getCustIdNumber(),replacePaymentConditionDto.getWithholdCategory());
				if (record == null || !record.getStatus().equals("0")) {// 不处于待审核状态
					throw new MarvelsBusinessException("代还款申请不处于待审核状态");
				}
//				if (new BigDecimal(replacePaymentConditionDto.getPaymentAmountAct())
//						.compareTo(record.getAmount()) != 0) {
//					throw new MarvelsBusinessException("审核金额与申请金额不一致");
//				}
				List<ReplacePaymentApplyInfo> list = mcfeCustomerLoanContractDao.selectContract(replacePaymentConditionDto);
				if (list == null || list.size() < 1) {
					throw new MarvelsBusinessException("合同信息不存在");
				}
				// 判断进件是否处于还款状态
				if (list.get(0).getContractStatus().equals("2") || list.get(0).getContractStatus().equals("3")
						|| list.get(0).getContractStatus().equals("10")) {
					throw new MarvelsBusinessException("进件不处于还款状态");
				}
//				if (!replacePaymentConditionDto.getPaymentWay().equals(record.getPaymentWay())) {// 不处于待审核状态
//					throw new MarvelsBusinessException("还款方式不一致");
//				}
				// 更新代还款/代偿审核
				UserDTO user = CacheUtils.getCacheUser();
				McfeWithholdCompensatoryDto compensatoryDto = new McfeWithholdCompensatoryDto();
				compensatoryDto.setRemarks(replacePaymentConditionDto.getRemarks());
				compensatoryDto.setUpdatedBy(user.getUserName());
				compensatoryDto.setUpdatedDate(new Date());
				compensatoryDto.setId(record.getId());
				compensatoryDto.setStatus("1");
				int count = compensatoryMapper.updateById(compensatoryDto);
				if (count < 1) {
					throw new MarvelsBusinessException("更新代还款/代偿审核状态失败");
				}
				// 判断还款计划对应的进件是否有处在正在冲账中的流水
				McfeRepaymentFlowDTO flowDTO = flowDao.selectDealingByLoanId(replacePaymentConditionDto.getLoanId());
				if (flowDTO != null) {
					MarvelsLogUtil.getInstance()
							.info(">>>>>>>>>>loanId:" + replacePaymentConditionDto.getLoanId() + ",有处在冲账中或未冲账的流水");
					throw new MarvelsBusinessException("存在未冲账的流水,请稍候再试");
				}
				McfePaymentWithholdDetailDTO detailDTO = detailDao.selectTradingByLoanId(loanId);
				if (detailDTO != null) {
					MarvelsLogUtil.getInstance()
					.info(">>>>>>>>>>loanId:" + loanId + ",存在处理中的代扣");
					throw new MarvelsBusinessException("存在处理中的代扣请稍候再试");
				}
				replacePaymentConditionDto.setExtensionDay(record.getExtensionDay());
				replacePaymentConditionDto.setPaymentAmountAct(record.getAmount()+"");
				replacePaymentConditionDto.setPaymentAmount(record.getAmount());
				compensatoryAdoptSuccess(replacePaymentConditionDto,record.getTransctionSeq());
				// 记录审核流水
				try {
					McfeWithholdCompensatoryLogDto logDto = new McfeWithholdCompensatoryLogDto();
					logDto.setAmount(new BigDecimal(replacePaymentConditionDto.getPaymentAmountAct()));
					logDto.setCustCardNo(record.getCustCardNo());
					logDto.setCustName(replacePaymentConditionDto.getTransferUserName());
					logDto.setLoanId(record.getLoanId());
					logDto.setMobile(record.getMobile());
					logDto.setStatus("1");// 0:待审核，1:通过，2：拒绝
					logDto.setCreatedDate(new Date());
					logDto.setUpdatedDate(new Date());
					logDto.setPayType("1");// 还款类型: 1-代还款;2-代提前结清;3-代偿;4-代偿提前结清
					logDto.setCreatedBy(user.getUserName());
					logDto.setUpdatedDate(new Date());
					logDto.setUpdatedBy(user.getUserName());
					logDto.setRemarks("代还款审核通过");
					logDto.setWithholdCategory(replacePaymentConditionDto.getWithholdCategory());
					logDao.insertSelective(logDto);
				} catch (Exception e) {
					MarvelsLogUtil.getInstance().error(">>>>记录代还款审核通过流水异常:", e);
				}
			}
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error(">>>>>loanId:" + loanId + ",代还款审核通过异常:", e);
			throw new MarvelsBusinessException(e.getMessage());
		} finally {
			if (!CacheUtils.isNotLock(key, loanId)) {// 如果是锁住的将所释放
				CacheUtils.del(key);
			}
		}
	}

	/**
	 * 审核通过成功处理
	 * @param replacePaymentConditionDto
	 * @throws MarvelsBusinessException
	 */
	public void compensatoryAdoptSuccess(ReplacePaymentConditionDto replacePaymentConditionDto,String transctionSeq) throws MarvelsBusinessException {
		if(StringUtils.isEmpty(replacePaymentConditionDto.getWithholdCategory())){
			throw new MarvelsBusinessException("代扣类别不能为空");
		}
		if(replacePaymentConditionDto.getWithholdCategory().equals("1")){//扣还款金额
			UserDTO user = CacheUtils.getCacheUser();
			// 持久化还款流水/冲销流水
			McamLoanApplyInfoDTO mcamLoanApplyInfoDTO = new McamLoanApplyInfoDTO();
			mcamLoanApplyInfoDTO.setLoanId(replacePaymentConditionDto.getLoanId());
			McamLoanApplyInfoDTO applyInfoData = approveApi.selectLoanApplyInfo(mcamLoanApplyInfoDTO);
			McfeRepaymentFlowDTO mcfeRepaymentFlowDto = new McfeRepaymentFlowDTO();
			BigDecimal auditAmount = new BigDecimal(replacePaymentConditionDto.getPaymentAmountAct()).setScale(2,
					BigDecimal.ROUND_HALF_DOWN);
			mcfeRepaymentFlowDto.setAmountAct(auditAmount);
			mcfeRepaymentFlowDto.setCustCardNo(applyInfoData.getCustCardNo());
			mcfeRepaymentFlowDto.setCustName(applyInfoData.getCustName());
			mcfeRepaymentFlowDto.setStatus("0");
			mcfeRepaymentFlowDto.setLoanId(replacePaymentConditionDto.getLoanId());
			mcfeRepaymentFlowDto.setBankCardNo(applyInfoData.getPaymentAcctNo());
			mcfeRepaymentFlowDto.setBankName(applyInfoData.getPaymentAcctName());
			mcfeRepaymentFlowDto.setBankHeadLink(applyInfoData.getPaymentBankHead());
			mcfeRepaymentFlowDto.setFundCode(applyInfoData.getFundCode());
			mcfeRepaymentFlowDto.setFundName(applyInfoData.getFundName());
			mcfeRepaymentFlowDto.setProductType(applyInfoData.getProductType());
			mcfeRepaymentFlowDto.setProductTypeName(applyInfoData.getProductTypeName());
			mcfeRepaymentFlowDto.setProductCode(applyInfoData.getProductCode());
			mcfeRepaymentFlowDto.setProductName(applyInfoData.getProductName());
			mcfeRepaymentFlowDto.setChannelCode(applyInfoData.getChannel());
			mcfeRepaymentFlowDto.setChannelName(applyInfoData.getChannelName());
			mcfeRepaymentFlowDto.setCreatedBy(user.getUserName());
			mcfeRepaymentFlowDto.setUpdatedBy(user.getUserName());
			mcfeRepaymentFlowDto.setCreatedDate(new Date());
			mcfeRepaymentFlowDto.setUpdatedDate(new Date());
			mcfeRepaymentFlowDto.setReqChannel("006");// 实际扣款渠道 001 快付通（云科贷）002 宝付（云科贷） 003  宝付（口袋） 004 宝付（渤海） 005 支付宝 006 运营'
			mcfeRepaymentFlowDto.setRtnOrderNo(replacePaymentConditionDto.getTradeSerialNumber());
			mcfeRepaymentFlowDto.setMobile(applyInfoData.getMobileNo());
			mcfeRepaymentFlowDto.setRepayStyle("3");
			mcfeRepaymentFlowDto.setPayType("1");//还款类型 1 - 还款  2 提前结清
			mcfeRepaymentFlowDto.setTranctionDate(new Date());
			mcfeRepaymentFlowDto.setTransctionSeq(transctionSeq);
			int countData = mcfeRepaymentFlowDao.insertSelective(mcfeRepaymentFlowDto);
			if (countData < 1) {
				throw new MarvelsBusinessException("持久化还款流水/冲销流水失败");
			}
		}else if(replacePaymentConditionDto.getWithholdCategory().equals("2")){//展期费
			//冲账展期费用
			withholdPaymentApi.extensionwithholdeSuccess(replacePaymentConditionDto.getLoanId(),new BigDecimal(replacePaymentConditionDto.getPaymentAmountAct()), replacePaymentConditionDto.getExtensionDay());

		}else{
			throw new MarvelsBusinessException("代扣类别不存在");
		}

	}


	@Override
	@Transactional(rollbackFor=Exception.class)
	public void replacePaymentAuditRefuse(ReplacePaymentConditionDto replacePaymentConditionDto)
			throws MarvelsBusinessException {
		// 判断进件是否处于还款状态
		if (StringUtils.isEmpty(replacePaymentConditionDto.getRemarks())) {
			throw new MarvelsBusinessException("请填写备注信息");
		}
		String withholdCategory=replacePaymentConditionDto.getWithholdCategory();
		if(StringUtils.isEmpty(withholdCategory)){
			throw new MarvelsBusinessException("代扣类别不能为空");
		}
		McfeWithholdCompensatoryDto record = compensatoryMapper.selectCompensatory(replacePaymentConditionDto.getLoanId(),
				"1",replacePaymentConditionDto.getCustIdNumber(),withholdCategory);
		// 查询审核流水表
		if (record == null || !record.getStatus().equals("0")) {// 不处于待审核状态
			throw new MarvelsBusinessException("代还款申请不处于待审核状态");
		}
		// 更新代还款/代偿审核
		UserDTO user = CacheUtils.getCacheUser();
		McfeWithholdCompensatoryDto compensatoryDto = new McfeWithholdCompensatoryDto();
		compensatoryDto.setRemarks(replacePaymentConditionDto.getRemarks());
		compensatoryDto.setUpdatedBy(user.getUserName());
		compensatoryDto.setUpdatedDate(new Date());
		compensatoryDto.setId(record.getId());
		compensatoryDto.setStatus("2");
		int count = compensatoryMapper.updateById(compensatoryDto);
		if (count < 1) {
			throw new MarvelsBusinessException("持久化代还款/代偿审核状态失败");
		}

		// 记录审核流水
		try {
			McfeWithholdCompensatoryLogDto logDto = new McfeWithholdCompensatoryLogDto();
			logDto.setAmount(record.getAmount());
			logDto.setCustCardNo(record.getCustCardNo());
			logDto.setCustName(record.getCustName());
			logDto.setLoanId(record.getLoanId());
			logDto.setMobile(record.getMobile());
			logDto.setStatus("2");// 0:待审核，1:通过，2：拒绝
			logDto.setCreatedDate(new Date());
			logDto.setUpdatedDate(new Date());
			logDto.setPayType("1");// 还款类型: 1-代还款;2-代提前结清;3-代偿;4-代偿提前结清
			logDto.setCreatedBy(user.getUserName());
			logDto.setUpdatedDate(new Date());
			logDto.setUpdatedBy(user.getUserName());
			logDto.setRemarks(replacePaymentConditionDto.getRemarks());
			logDao.insertSelective(logDto);
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error(">>>>记录代还款审核拒绝流水异常:", e);
		}
	}

	@Override
	public Page<ReplacePaymentApplyInfo> replacePaymentAdoptList(ReplacePaymentConditionDto replacePaymentConditionDto)
			throws MarvelsBusinessException {
		int pageSize = replacePaymentConditionDto.getPageSize();
		int pageNum = replacePaymentConditionDto.getPageNum();
		if (pageSize < 1) {
			pageSize = PageConstant.PAGESIZE;
		}
		if (pageNum < 1) {
			pageNum = PageConstant.CURRPAGE;
		}
		PageHelper.startPage(pageNum, pageSize);
		replacePaymentConditionDto.setPayType("1");// 还款类型:
													// 1-代还款;2-代提前结清;3-代偿;4-代偿提前结清
		replacePaymentConditionDto.setAuditStatus("1");//0:待审核，1:通过，2：拒绝
		return compensatoryMapper.selectAdoptData(replacePaymentConditionDto);
	}

	@Override
	public Page<ReplacePaymentApplyInfo> replacePaymentRefuseList(ReplacePaymentConditionDto replacePaymentConditionDto)
			throws MarvelsBusinessException {
		int pageSize = replacePaymentConditionDto.getPageSize();
		int pageNum = replacePaymentConditionDto.getPageNum();
		if (pageSize < 1) {
			pageSize = PageConstant.PAGESIZE;
		}
		if (pageNum < 1) {
			pageNum = PageConstant.CURRPAGE;
		}
		PageHelper.startPage(pageNum, pageSize);
		replacePaymentConditionDto.setPayType("1");// 还款类型:  1-代还款;2-代提前结清;3-代偿;4-代偿提前结清
		return compensatoryMapper.selectRefuseData(replacePaymentConditionDto);
	}

	@Override
	public Map<String, Object> queryPayment(ReplacePaymentConditionDto replacePaymentConditionDto)
			throws MarvelsBusinessException {
		int pageSize = replacePaymentConditionDto.getPageSize();
		int pageNum = replacePaymentConditionDto.getPageNum();
		if (pageSize < 1) {
			pageSize = PageConstant.PAGESIZE;
		}
		if (pageNum < 1) {
			pageNum = PageConstant.CURRPAGE;
		}
		PageHelper.startPage(pageNum, pageSize);
		Page<ReplacePaymentApplyInfo> list = compensatoryMapper.selectAllData(replacePaymentConditionDto);
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("data",list);
		map.put("total",list.getTotal());
		ReplacePaymentApplyInfo dto = compensatoryMapper.selectAllAmountStatic(replacePaymentConditionDto);
		List<ReplacePaymentApplyInfo> staticList=new ArrayList<ReplacePaymentApplyInfo>();
		staticList.add(dto);
		map.put("static",staticList);
		return map;
	}

	@Override
	public MarvelsResultDTO earlyPaymentApplyInfo(ReplacePaymentConditionDto replacePaymentConditionDto)
			throws MarvelsBusinessException {
		int pageSize = replacePaymentConditionDto.getPageSize();
		int pageNum = replacePaymentConditionDto.getPageNum();
		if (pageSize < 1) {
			pageSize = PageConstant.PAGESIZE;
		}
		if (pageNum < 1) {
			pageNum = PageConstant.CURRPAGE;
		}
		PageHelper.startPage(pageNum, pageSize);
		Page<ReplacePaymentApplyInfo> list = mcfeCustomerLoanContractDao.selectContract(replacePaymentConditionDto);
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("list", list);
		map.put("total", list.getTotal());
		// 查询已拒绝份数,已经通过份数
		replacePaymentConditionDto.setPayType("2");
		ReplacePaymentAuditStatistics statistics = compensatoryMapper.selectStatistics(replacePaymentConditionDto);
		map.put("statistics", statistics);
		return MarvelsResultDTO.getResult(MarvelsErrorCode.SUCCESS.getValue(), "查询成功", map);
	}

	@Override
	@Transactional(rollbackFor=Exception.class)
	public  void earlyPaymentApply(ReplacePaymentConditionDto replacePaymentConditionDto)
			throws MarvelsBusinessException {
		// 先判断金额
		if (StringUtils.isEmpty(replacePaymentConditionDto.getPaymentAmountAct())) {
			throw new MarvelsBusinessException("实还金额不能为空");
		}
		if (StringUtils.isEmpty(replacePaymentConditionDto.getPaymentWay())) {
			throw new MarvelsBusinessException("还款方式不能为空");
		}
		if (StringUtils.isEmpty(replacePaymentConditionDto.getTransferUserName())) {
			throw new MarvelsBusinessException("转账人姓名不能为空");
		}
		// 判断填入金额是否大于剩余金额
		// if (new BigDecimal(replacePaymentConditionDto.getPaymentAmountAct())
		// .compareTo(replacePaymentConditionDto.getPaymentAmount()) > 0) {
		// throw new MarvelsBusinessException("实还金额大于剩余应还金额");
		// }
		String loanId = replacePaymentConditionDto.getLoanId();
		// 加锁 避免重复插入数据
		String key = RedisKeyConstant.HAND_PAYMENT_WITHHOLD + loanId;
		boolean isNotLock = false;
		try {
			isNotLock = CacheUtils.isNotLock(key, loanId);
			if (isNotLock) {
				// 先将这个key设置过期时间
				CacheUtils.setExpire(key, 60);
				List<ReplacePaymentApplyInfo> list = mcfeCustomerLoanContractDao.selectContract(replacePaymentConditionDto);
				if (list == null || list.size() < 1) {
					throw new MarvelsBusinessException("合同信息不存在");
				}
				// 判断进件是否处于还款状态
				if (list.get(0).getContractStatus().equals("2") || list.get(0).getContractStatus().equals("3")) {
					throw new MarvelsBusinessException("进件不处于还款状态");
				}
				McfeWithholdCompensatoryDto record = compensatoryMapper.selectCompensatory(
						replacePaymentConditionDto.getLoanId(), "2", replacePaymentConditionDto.getCustIdNumber(),"1");
				// 查询审核流水表
				if (record != null && record.getStatus().equals("0")) {// 处于待审核状态
					throw new MarvelsBusinessException("已有申请正在审核中请稍候");
				}
				UserDTO user = CacheUtils.getCacheUser();
				if (record != null) {
					McfeWithholdCompensatoryDto compensatoryDto = new McfeWithholdCompensatoryDto();
					compensatoryDto.setRemarks(replacePaymentConditionDto.getRemarks());
					compensatoryDto.setUpdatedBy(user.getUserName());
					compensatoryDto.setUpdatedDate(new Date());
					compensatoryDto.setId(record.getId());
					compensatoryDto.setStatus("0");
					int count = compensatoryMapper.updateById(compensatoryDto);
					if (count < 1) {
						throw new MarvelsBusinessException("更新代还款/代偿审核状态失败");
					}
				} else {
					// 持久化审核申请信息
					record = new McfeWithholdCompensatoryDto();
					record.setAmount(new BigDecimal(replacePaymentConditionDto.getPaymentAmountAct()));
					record.setCustCardNo(list.get(0).getCustCardNo());
					record.setCustName(replacePaymentConditionDto.getTransferUserName());
					record.setLoanId(list.get(0).getLoanId());
					record.setMobile(list.get(0).getCustMobile());
					record.setPaymentWay(replacePaymentConditionDto.getPaymentWay());
					record.setStatus("0");// 0:待审核，1:通过，2：拒绝
					record.setCreatedDate(new Date());
					record.setUpdatedDate(new Date());
					record.setPayType("2");// 还款类型: 1-代还款;2-代提前结清;3-代偿;4-代偿提前结清
					record.setCreatedBy(user.getUserName());
					record.setUpdatedDate(new Date());
					record.setRemarks(replacePaymentConditionDto.getRemarks());
					record.setPaymentWay(replacePaymentConditionDto.getPaymentWay());// 还款方式 1 对公转账  2  支付宝转账
					record.setUpdatedBy(user.getUserName());
					int count = compensatoryMapper.insertSelective(record);
					if (count < 1) {
						throw new MarvelsBusinessException("持久化审核申请信息失败");
					}
				}
				// 记录申请流水
				try {
					McfeWithholdCompensatoryLogDto logDto = new McfeWithholdCompensatoryLogDto();
					logDto.setAmount(new BigDecimal(replacePaymentConditionDto.getPaymentAmountAct()));
					logDto.setCustCardNo(list.get(0).getCustCardNo());
					logDto.setCustName(list.get(0).getCustName());
					logDto.setLoanId(list.get(0).getLoanId());
					logDto.setMobile(list.get(0).getCustMobile());
					logDto.setStatus("0");// 0:待审核，1:通过，2：拒绝
					logDto.setCreatedDate(new Date());
					logDto.setUpdatedDate(new Date());
					logDto.setPayType("2");// 还款类型: 1-代还款;2-代提前结清;3-代偿;4-代偿提前结清
					logDto.setCreatedBy(user.getUserName());
					logDto.setUpdatedDate(new Date());
					logDto.setUpdatedBy(user.getUserName());
					logDto.setRemarks("提前结清申请");
					logDao.insertSelective(logDto);
				} catch (Exception e) {
					MarvelsLogUtil.getInstance().error(">>>>记录提前结清申请异常:", e);
				}
			}
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error(">>>>>loanId:" + loanId + ",代还款审核通过异常:", e);
			throw new MarvelsBusinessException(e.getMessage());
		} finally {
			if (!CacheUtils.isNotLock(key, loanId)) {// 如果是锁住的将所释放
				CacheUtils.del(key);
			}
		}
		return;
	}

	@Override
	public Page<ReplacePaymentApplyInfo> earlyPaymentAuditList(ReplacePaymentConditionDto replacePaymentConditionDto)
			throws MarvelsBusinessException {
		int pageSize = replacePaymentConditionDto.getPageSize();
		int pageNum = replacePaymentConditionDto.getPageNum();
		if (pageSize < 1) {
			pageSize = PageConstant.PAGESIZE;
		}
		if (pageNum < 1) {
			pageNum = PageConstant.CURRPAGE;
		}
		PageHelper.startPage(pageNum, pageSize);
		replacePaymentConditionDto.setAuditStatus("0");// 审核中状态
		replacePaymentConditionDto.setPayType("2");// 还款类型:1-代还款;2-代提前结清;3-代偿;4-代偿提前结清
		return mcfeCustomerLoanContractDao.selectContract(replacePaymentConditionDto);
	}

	@Override
	@Transactional(rollbackFor=Exception.class)
	public  void earlyPaymentAuditAdopt(ReplacePaymentConditionDto replacePaymentConditionDto)
			throws MarvelsBusinessException {

		if (StringUtils.isEmpty(replacePaymentConditionDto.getPaymentWay())) {
			throw new MarvelsBusinessException("请选择还款方式");
		}
		if (StringUtils.isEmpty(replacePaymentConditionDto.getPaymentAmountAct())) {
			throw new MarvelsBusinessException("请输入实还金额");
		}
		String loanId = replacePaymentConditionDto.getLoanId();
		// 加锁 避免重复插入数据
		String key = RedisKeyConstant.HAND_PAYMENT_WITHHOLD + loanId;
		boolean isNotLock = false;
		try {
			isNotLock = CacheUtils.isNotLock(key, loanId);
			if (isNotLock) {
				// 先将这个key设置过期时间
				CacheUtils.setExpire(key, 60);
				// 查询审核流水表
				McfeWithholdCompensatoryDto record = compensatoryMapper.selectCompensatory(
						replacePaymentConditionDto.getLoanId(), "2", replacePaymentConditionDto.getCustIdNumber(),"1");
				BigDecimal auditAmount = new BigDecimal(replacePaymentConditionDto.getPaymentAmountAct()).setScale(2,
						BigDecimal.ROUND_HALF_DOWN);
				BigDecimal applyAmount = record.getAmount().setScale(2, BigDecimal.ROUND_HALF_DOWN);
				if (!auditAmount.equals(applyAmount)) {
					throw new MarvelsBusinessException("审核金额与申请金额不一致");
				}
				if (record == null || !record.getStatus().equals("0")) {// 不处于待审核状态
					throw new MarvelsBusinessException("提前结清申请不处于待审核状态");
				}
				if (!replacePaymentConditionDto.getPaymentWay().equals(record.getPaymentWay())) {// 不处于待审核状态
					throw new MarvelsBusinessException("还款方式不一致");
				}
				List<ReplacePaymentApplyInfo> list = mcfeCustomerLoanContractDao.selectContract(replacePaymentConditionDto);
				if (list == null || list.size() < 1) {
					throw new MarvelsBusinessException("合同信息不存在");
				}
				// 判断进件是否处于还款状态
				if (list.get(0).getContractStatus().equals("2") || list.get(0).getContractStatus().equals("3")
						|| list.get(0).getContractStatus().equals("10")) {
					throw new MarvelsBusinessException("进件不处于还款状态");
				}
				// 更新代还款/代偿审核
				UserDTO user = CacheUtils.getCacheUser();
				McfeWithholdCompensatoryDto compensatoryDto = new McfeWithholdCompensatoryDto();
				compensatoryDto.setRemarks(replacePaymentConditionDto.getRemarks());
				compensatoryDto.setUpdatedBy(user.getUserName());
				compensatoryDto.setUpdatedDate(new Date());
				compensatoryDto.setId(record.getId());
				compensatoryDto.setStatus("1");
				int count = compensatoryMapper.updateById(compensatoryDto);
				if (count < 1) {
					throw new MarvelsBusinessException("更新代还款/代偿审核状态失败");
				}
				// 判断还款计划对应的进件是否有处在正在冲账中的流水
				McfeRepaymentFlowDTO flowDTO = flowDao.selectDealingByLoanId(replacePaymentConditionDto.getLoanId());
				if (flowDTO != null) {
					MarvelsLogUtil.getInstance()
							.info(">>>>>>>>>>loanId:" + replacePaymentConditionDto.getLoanId() + ",有处在冲账中或未冲账的流水");
					throw new MarvelsBusinessException("存在未冲账的流水,请稍候再试");
				}
				McfePaymentWithholdDetailDTO detailDTO = detailDao.selectTradingByLoanId(loanId);
				if (detailDTO != null) {
					MarvelsLogUtil.getInstance()
					.info(">>>>>>>>>>loanId:" + loanId + ",存在处理中的代扣");
					throw new MarvelsBusinessException("存在处理中的代扣请稍候再试");
				}
				// 持久化还款流水/冲销流水
				McamLoanApplyInfoDTO mcamLoanApplyInfoDTO = new McamLoanApplyInfoDTO();
				mcamLoanApplyInfoDTO.setLoanId(replacePaymentConditionDto.getLoanId());
				McamLoanApplyInfoDTO applyInfoData = approveApi.selectLoanApplyInfo(mcamLoanApplyInfoDTO);
				McfeRepaymentFlowDTO mcfeRepaymentFlowDto = new McfeRepaymentFlowDTO();
				mcfeRepaymentFlowDto.setAmountAct(auditAmount);
				mcfeRepaymentFlowDto.setCustCardNo(applyInfoData.getCustCardNo());
				mcfeRepaymentFlowDto.setCustName(applyInfoData.getCustName());
				mcfeRepaymentFlowDto.setStatus("0");
				mcfeRepaymentFlowDto.setLoanId(replacePaymentConditionDto.getLoanId());
				mcfeRepaymentFlowDto.setBankCardNo(applyInfoData.getPaymentAcctNo());
				mcfeRepaymentFlowDto.setBankName(applyInfoData.getPaymentAcctName());
				mcfeRepaymentFlowDto.setBankHeadLink(applyInfoData.getPaymentBankHead());
				mcfeRepaymentFlowDto.setFundCode(applyInfoData.getFundCode());
				mcfeRepaymentFlowDto.setFundName(applyInfoData.getFundName());
				mcfeRepaymentFlowDto.setProductType(applyInfoData.getProductType());
				mcfeRepaymentFlowDto.setProductTypeName(applyInfoData.getProductTypeName());
				mcfeRepaymentFlowDto.setProductCode(applyInfoData.getProductCode());
				mcfeRepaymentFlowDto.setProductName(applyInfoData.getProductName());
				mcfeRepaymentFlowDto.setChannelCode(applyInfoData.getChannel());
				mcfeRepaymentFlowDto.setChannelName(applyInfoData.getChannelName());
				mcfeRepaymentFlowDto.setCreatedBy(user.getUserName());
				mcfeRepaymentFlowDto.setUpdatedBy(user.getUserName());
				mcfeRepaymentFlowDto.setCreatedDate(new Date());
				mcfeRepaymentFlowDto.setUpdatedDate(new Date());
				mcfeRepaymentFlowDto.setMobile(applyInfoData.getMobileNo());
				mcfeRepaymentFlowDto.setRepayStyle("3");
				mcfeRepaymentFlowDto.setPayType("2");
				mcfeRepaymentFlowDto.setTranctionDate(new Date());
				String reqNo = GenerateReqNoUtils.transctionReq("TX");
				mcfeRepaymentFlowDto.setTransctionSeq(reqNo);
				int countData = mcfeRepaymentFlowDao.insertSelective(mcfeRepaymentFlowDto);
				if (countData < 1) {
					throw new MarvelsBusinessException("持久化还款流水/冲销流水失败");
				}
				// 记录审核流水
				try {
					McfeWithholdCompensatoryLogDto logDto = new McfeWithholdCompensatoryLogDto();
					logDto.setAmount(new BigDecimal(replacePaymentConditionDto.getPaymentAmountAct()));
					logDto.setCustCardNo(record.getCustCardNo());
					logDto.setCustName(replacePaymentConditionDto.getTransferUserName());
					logDto.setLoanId(record.getLoanId());
					logDto.setMobile(record.getMobile());
					logDto.setStatus("1");// 0:待审核，1:通过，2：拒绝
					logDto.setCreatedDate(new Date());
					logDto.setUpdatedDate(new Date());
					logDto.setPayType("2");// 还款类型: 1-代还款;2-代提前结清;3-代偿;4-代偿提前结清
					logDto.setCreatedBy(user.getUserName());
					logDto.setUpdatedDate(new Date());
					logDto.setUpdatedBy(user.getUserName());
					logDto.setRemarks("提前结清审核通过");
					logDao.insertSelective(logDto);
				} catch (Exception e) {
					MarvelsLogUtil.getInstance().error(">>>>记录提前结清审核通过流水异常:", e);
				}
			}
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error(">>>>>loanId:" + loanId + ",提前结清审核通过异常:", e);
			throw new MarvelsBusinessException(e.getMessage());
		} finally {
			if (!CacheUtils.isNotLock(key, loanId)) {// 如果是锁住的将所释放
				CacheUtils.del(key);
			}
		}
	}

	@Override
	@Transactional(rollbackFor=Exception.class)
	public void earlyPaymentAuditRefuse(ReplacePaymentConditionDto replacePaymentConditionDto)
			throws MarvelsBusinessException {
		// 判断进件是否处于还款状态
		if (StringUtils.isEmpty(replacePaymentConditionDto.getRemarks())) {
			throw new MarvelsBusinessException("请填写备注信息");
		}
		McfeWithholdCompensatoryDto record = compensatoryMapper.selectCompensatory(replacePaymentConditionDto.getLoanId(),
				"2",replacePaymentConditionDto.getCustIdNumber(),"1");
		// 查询审核流水表
		if (record == null || !record.getStatus().equals("0")) {// 不处于待审核状态
			throw new MarvelsBusinessException("提前结清申请不处于待审核状态");
		}

		// 更新代还款/代偿审核
		UserDTO user = CacheUtils.getCacheUser();
		McfeWithholdCompensatoryDto compensatoryDto = new McfeWithholdCompensatoryDto();
		compensatoryDto.setRemarks(replacePaymentConditionDto.getRemarks());
		compensatoryDto.setUpdatedBy(user.getUserName());
		compensatoryDto.setUpdatedDate(new Date());
		compensatoryDto.setId(record.getId());
		compensatoryDto.setStatus("2");
		int count = compensatoryMapper.updateById(compensatoryDto);
		if (count < 1) {
			throw new MarvelsBusinessException("持久化代还款/代偿审核状态失败");
		}
		// 记录审核流水
		McfeWithholdCompensatoryLogDto logDto = new McfeWithholdCompensatoryLogDto();
		logDto.setAmount(record.getAmount());
		logDto.setCustCardNo(record.getCustCardNo());
		logDto.setCustName(record.getCustName());
		logDto.setLoanId(record.getLoanId());
		logDto.setMobile(record.getMobile());
		logDto.setStatus("2");// 0:待审核，1:通过，2：拒绝
		logDto.setCreatedDate(new Date());
		logDto.setUpdatedDate(new Date());
		logDto.setPayType("2");// 还款类型: 1-代还款;2-代提前结清;3-代偿;4-代偿提前结清
		logDto.setCreatedBy(user.getUserName());
		logDto.setUpdatedDate(new Date());
		logDto.setRemarks(replacePaymentConditionDto.getRemarks());
		logDto.setUpdatedBy(user.getUserName());
		try {
			logDao.insertSelective(logDto);
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error(">>>>记录提前结清审核拒绝流水异常:", e);
		}
	}

	@Override
	public Page<ReplacePaymentApplyInfo> earlyPaymentAdoptList(ReplacePaymentConditionDto replacePaymentConditionDto)
			throws MarvelsBusinessException {
		int pageSize = replacePaymentConditionDto.getPageSize();
		int pageNum = replacePaymentConditionDto.getPageNum();
		if (pageSize < 1) {
			pageSize = PageConstant.PAGESIZE;
		}
		if (pageNum < 1) {
			pageNum = PageConstant.CURRPAGE;
		}
		PageHelper.startPage(pageNum, pageSize);
		replacePaymentConditionDto.setPayType("2");// 还款类型:
													// 1-代还款;2-代提前结清;3-代偿;4-代偿提前结清
		return compensatoryMapper.selectAdoptData(replacePaymentConditionDto);
	}

	@Override
	public Page<ReplacePaymentApplyInfo> earlyPaymentRefuseList(ReplacePaymentConditionDto replacePaymentConditionDto)
			throws MarvelsBusinessException {
		int pageSize = replacePaymentConditionDto.getPageSize();
		int pageNum = replacePaymentConditionDto.getPageNum();
		if (pageSize < 1) {
			pageSize = PageConstant.PAGESIZE;
		}
		if (pageNum < 1) {
			pageNum = PageConstant.CURRPAGE;
		}
		PageHelper.startPage(pageNum, pageSize);
		replacePaymentConditionDto.setPayType("2");// 还款类型:
													// 1-代还款;2-代提前结清;3-代偿;4-代偿提前结清
		return compensatoryMapper.selectRefuseData(replacePaymentConditionDto);
	}

	@Override
	public EarlyPaymentCalculatDto calculatEarlypayment(ReplacePaymentConditionDto replacePaymentConditionDto)
			throws MarvelsBusinessException {
		String loanId = replacePaymentConditionDto.getLoanId();
		EarlyPaymentCalculatDto earlyPaymentCalculatDto = new EarlyPaymentCalculatDto();
		// 利率
		McfeCustomerLoanContractDTO loanContractDTO = mcfeCustomerLoanContractDao.selectContractByLoanId(loanId);
		McptProduct productDtO = new  McptProduct();
		productDtO.setProductCode(loanContractDTO.getProductCode());
		MarvelsResultDTO rateFeeDTO = iProductInfoApi.queryFeeRateByProductCode(productDtO);
		McptProductFundRelationDto mcptProductFundRelationDto = null;// 查询产品小类利率
		String josnStr = JSON.toJSONString(rateFeeDTO.getData());
		ProductMsgInfoDTO rateFeeMap = JSON.toJavaObject(JSON.parseObject(josnStr), ProductMsgInfoDTO.class);
		McptAmortMethodDTO mcptAmortMethodDTO = rateFeeMap.getMcptAmortMethodDTO();
		List<McptProductFundRelationDto> mcptProductFundRelationDtoList = (List<McptProductFundRelationDto>) rateFeeMap
				.getMcptProductFundRelationDto();
		if (mcptProductFundRelationDtoList != null && mcptProductFundRelationDtoList.size() > 0) {
			mcptProductFundRelationDto = mcptProductFundRelationDtoList.get(0);
		} else {
			mcptProductFundRelationDto = new McptProductFundRelationDto();
		}
		BigDecimal dayRate = mcptProductFundRelationDto.getRate().divide(BigDecimal.valueOf(365), MarvelsConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP);
		int roundFlag = 0;

		if (mcptAmortMethodDTO.getRoundUp()==MarvelsConstant.ROUND_HALF_UP ) {
			roundFlag = BigDecimal.ROUND_HALF_UP;
		} else if (mcptAmortMethodDTO.getRoundUp()==MarvelsConstant.ROUND_UP) {
			roundFlag = BigDecimal.ROUND_UP;
		} else if (mcptAmortMethodDTO.getRoundUp()==MarvelsConstant.ROUND_DOWN) {
			roundFlag = BigDecimal.ROUND_DOWN;
		}

		earlyPaymentCalculatDto.setContractBeginDate(DateUtils.getDateStr(loanContractDTO.getCreatedDate(), "yyyy-MM-dd"));
		earlyPaymentCalculatDto.setContractId(loanContractDTO.getContractNo());
		String contractIdStatus="";
		if(0==loanContractDTO.getStatus()){
			contractIdStatus="正常";
		}else if(1==loanContractDTO.getStatus()){
			contractIdStatus="逾期";
		}else if(2==loanContractDTO.getStatus()){
			contractIdStatus="结清";
		}else if(3==loanContractDTO.getStatus()){
			contractIdStatus="提前结清";
		}
		earlyPaymentCalculatDto.setContractIdStatus(contractIdStatus);
		McfeCustomerRepaymentPlanDTO repaymentPlanDTO = planDao.selectCurrFee(loanContractDTO);
		earlyPaymentCalculatDto.setCurrFee(repaymentPlanDTO.getCurrFee());
		earlyPaymentCalculatDto.setCurrOverdueFee(repaymentPlanDTO.getCurrOverdueFee());
		earlyPaymentCalculatDto.setCurrTerm(loanContractDTO.getCurrTenor());
		earlyPaymentCalculatDto.setCustIdNumber(loanContractDTO.getCustCardNo());
		earlyPaymentCalculatDto.setCustName(loanContractDTO.getCustName());
		try {
			AmountDTO amountDTO = loanAfterInfoApi.prePayTrail(loanId);
			earlyPaymentCalculatDto.setEarlyPaymentAmount(amountDTO.getPreAmount());
			earlyPaymentCalculatDto.setEarlyPaymentFee(amountDTO.getPreFee());
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().info(">>>>>>>>>loanId:"+loanId+e.getMessage()+"提前还款试算异常");
		}
		earlyPaymentCalculatDto.setLoanPrincipal(loanContractDTO.getPrincipal());
		// 重构未付利息
		// 天数 当前日期-最后还款日期
		BigDecimal days = BigDecimal.ZERO;
		// 获取当前冲账流水
		List<McfeReversalDetailDTO> list = reversalDetailDao.selectMcfeReversalDetailDtoListByLoanId(loanId);
		MarvelsLogUtil.getInstance().info("McfeReversalDetailDTO:"+list.toString());
		// 当天已还本金
		BigDecimal principalOs = BigDecimal.ZERO;
		//当天已还利息
		BigDecimal interestOs = BigDecimal.ZERO;
		Date payDate = null;
		for(McfeReversalDetailDTO item : list){
			if(item.getTransactionCode().equals("principal")){
				principalOs = principalOs.add(item.getAmount());
			}
			if(item.getTransactionCode().equals("interest")){
				interestOs = interestOs.add(item.getAmount());
				if(payDate==null){
					payDate = item.getReversalDate();
				}
			}
		}

		if(payDate!=null){
			// 已经还过
			days = BigDecimal.valueOf(DateUtils.diffTowDate(payDate,new Date()));
		}else{
			// 未还过
			days = BigDecimal.valueOf(DateUtils.diffTowDate(loanContractDTO.getStartDate(),new Date())+1);
//			if(days.equals( BigDecimal.ZERO)){
//				days = BigDecimal.valueOf(1);
//			}else{
//				days.add(new BigDecimal(1));
//			}
		}
		// 判断是否已经还过利息提前结清试算处理异常
		MarvelsLogUtil.getInstance().info("dayRate:"+dayRate.toString());
		MarvelsLogUtil.getInstance().info("days:"+days.toString());
		BigDecimal reInterestOs = dayRate.multiply(loanContractDTO.getPrincipalOs()).multiply(days).setScale(2, roundFlag);
//		BigDecimal remianCost = loanContractDTO.getPrincipalOs().add(loanContractDTO.getInterestOs())
//				.add(loanContractDTO.getConsultingFeeOs()).add(loanContractDTO.getConsultingFeeOs())
//				.add(loanContractDTO.getManagementFeeOs()).add(loanContractDTO.getPenaltyFeeOs())
//				.add(loanContractDTO.getLateFeeOs()).add(loanContractDTO.getPreTerminateFeeOs())
//				.add(loanContractDTO.getMiscFeeOs()).add(loanContractDTO.getPlatformFeeOs())
//				.add(loanContractDTO.getRiskFeeOs())
//				.subtract(loanContractDTO.getPrincipalWaive().add(loanContractDTO.getInterestWaive())
//						.add(loanContractDTO.getConsultingFeeWaive()).add(loanContractDTO.getConsultingFeeWaive())
//						.add(loanContractDTO.getManagementFeeWaive()).add(loanContractDTO.getPenaltyFeeWaive())
//						.add(loanContractDTO.getLateFeeWaive()).add(loanContractDTO.getPreTerminateFeeWaive())
//						.add(loanContractDTO.getMiscFeeWaive()).add(loanContractDTO.getPlatformFeeWaive())
//						.add(loanContractDTO.getRiskFeeWaive()));
//		earlyPaymentCalculatDto.setRemianCost(remianCost);
//		earlyPaymentCalculatDto.setRemianInterest(loanContractDTO.getInterestOs());
//		earlyPaymentCalculatDto.setRemianPrincipal(loanContractDTO.getPrincipalOs());
		BigDecimal remianCost = loanContractDTO.getPrincipalOs().add(reInterestOs)
				.add(loanContractDTO.getConsultingFeeOs()).add(loanContractDTO.getConsultingFeeOs())
				.add(loanContractDTO.getManagementFeeOs()).add(loanContractDTO.getPenaltyFeeOs())
				.add(loanContractDTO.getLateFeeOs()).add(loanContractDTO.getPreTerminateFeeOs())
				.add(loanContractDTO.getMiscFeeOs()).add(loanContractDTO.getPlatformFeeOs())
				.add(loanContractDTO.getRiskFeeOs())
				.subtract(loanContractDTO.getPrincipalWaive().add(loanContractDTO.getInterestWaive())
						.add(loanContractDTO.getConsultingFeeWaive()).add(loanContractDTO.getConsultingFeeWaive())
						.add(loanContractDTO.getManagementFeeWaive()).add(loanContractDTO.getPenaltyFeeWaive())
						.add(loanContractDTO.getLateFeeWaive()).add(loanContractDTO.getPreTerminateFeeWaive())
						.add(loanContractDTO.getMiscFeeWaive()).add(loanContractDTO.getPlatformFeeWaive())
						.add(loanContractDTO.getRiskFeeWaive()));
		earlyPaymentCalculatDto.setRemianCost(remianCost);
		earlyPaymentCalculatDto.setRemianInterest(reInterestOs);
		earlyPaymentCalculatDto.setRemianPrincipal(loanContractDTO.getPrincipalOs());

		BigDecimal repaymentAmount =loanContractDTO.getPrincipalOs().add(loanContractDTO.getInterestOs())
				.add(loanContractDTO.getConsultingFeeOs()).add(loanContractDTO.getConsultingFeeOs())
				.add(loanContractDTO.getManagementFeeOs()).add(loanContractDTO.getPreTerminateFeeOs())
				.add(loanContractDTO.getMiscFeeOs()).add(loanContractDTO.getPlatformFeeOs())
				.add(loanContractDTO.getRiskFeeOs()).add(loanContractDTO.getPrincipalOs().add(loanContractDTO.getInterestOs())
						.add(loanContractDTO.getConsultingFeeOs()).add(loanContractDTO.getConsultingFeeOs())
						.add(loanContractDTO.getManagementFeeOs()).add(loanContractDTO.getPreTerminateFeeOs())
						.add(loanContractDTO.getMiscFeeOs()).add(loanContractDTO.getPlatformFeeOs())
						.add(loanContractDTO.getRiskFeeOs()))
				.subtract(loanContractDTO.getPrincipalWaive().add(loanContractDTO.getInterestWaive())
						.add(loanContractDTO.getConsultingFeeWaive()).add(loanContractDTO.getConsultingFeeWaive())
						.add(loanContractDTO.getManagementFeeWaive()).add(loanContractDTO.getPreTerminateFeeWaive())
						.add(loanContractDTO.getMiscFeeWaive()).add(loanContractDTO.getPlatformFeeWaive())
						.add(loanContractDTO.getRiskFeeWaive()));
		earlyPaymentCalculatDto.setRemianCost(remianCost);
		earlyPaymentCalculatDto.setContractId(loanId);
		earlyPaymentCalculatDto.setRepaymentAmount(repaymentAmount);
		MarvelsLogUtil.getInstance().info("earlyPaymentCalculatDto:"+earlyPaymentCalculatDto.toString());
		return earlyPaymentCalculatDto;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void sellBackDeal(SellBackCondition sellBackCondition) throws MarvelsBusinessException {
		long compensatoryId = sellBackCondition.getCompensatoryId();
		// 查询代还款 或者代展期记录
		McfeWithholdCompensatoryDto compensatoryDto = compensatoryMapper.selectById(compensatoryId);
		String loanId = compensatoryDto.getLoanId();
		// 加锁 避免重复插入数据
		String key = RedisKeyConstant.HAND_PAYMENT_WITHHOLD + loanId;
		boolean isNotLock = false;
		try {
			isNotLock = CacheUtils.isNotLock(key, loanId);
			if (isNotLock) {
				compensatoryDto = compensatoryMapper.selectById(compensatoryId);//重新查一遍
				if("1".equals(compensatoryDto.getIsSell())){//已经回销
					throw new MarvelsBusinessException("记录已回销");
				}
				String withholdCategory = compensatoryDto.getWithholdCategory();// 扣款类别 1  扣还款计划金额 2 扣展期费
				if (withholdCategory.equals("2")) {// 展期
					try {
						sellBackExtension(compensatoryDto.getLoanId(), compensatoryDto.getExtensionDay(),
								compensatoryDto.getAmount(), compensatoryId);
					} catch (MarvelsBusinessException e) {
						throw e;
					} catch (Exception e) {
						MarvelsLogUtil.getInstance().error(">>>>>loanId" + compensatoryDto.getLoanId() + "展期回退异常",e);
						throw new MarvelsBusinessException("展期回销异常");
					}
				} else if (withholdCategory.equals("1")) {// 还款
					try {
						sellBackPayment(compensatoryDto, compensatoryId);
					} catch (MarvelsBusinessException e) {
						throw e;
					} catch (Exception e) {
						MarvelsLogUtil.getInstance().error(">>>>>loanId" + compensatoryDto.getLoanId() + "展期回退异常",e);
						throw new MarvelsBusinessException("还款回销异常");
					}
				} else {
					throw new MarvelsBusinessException("回销扣款类别异常");
				}
				// 记录审核流水
				UserDTO user = CacheUtils.getCacheUser();
				try {
					McfeWithholdCompensatoryLogDto logDto = new McfeWithholdCompensatoryLogDto();
					logDto.setAmount(compensatoryDto.getAmount());
					logDto.setCustCardNo(compensatoryDto.getCustCardNo());
					logDto.setCustName(compensatoryDto.getCustName());
					logDto.setLoanId(compensatoryDto.getLoanId());
					logDto.setMobile(compensatoryDto.getMobile());
					logDto.setStatus("4");// 0:待审核，1:通过，2：拒绝 4回退
					logDto.setCreatedDate(new Date());
					logDto.setUpdatedDate(new Date());
					logDto.setPayType(compensatoryDto.getPayType());// 还款类型:
																	// 1-代还款;2-代提前结清;3-代偿;4-代偿提前结清
					logDto.setCreatedBy(user.getUserCode());
					logDto.setUpdatedDate(new Date());
					logDto.setUpdatedBy(user.getUserCode());
					logDto.setRemarks("代还款/代展期回退");
					logDto.setWithholdCategory(compensatoryDto.getWithholdCategory());
					logDao.insertSelective(logDto);
				} catch (Exception e) {
					MarvelsLogUtil.getInstance().error(">>>>记录提前结清审核通过流水异常:", e);
				}
				// 将代还款 或者代展期记录 更新为已回销
				McfeWithholdCompensatoryDto dto = new McfeWithholdCompensatoryDto();
				dto.setId(compensatoryId);
				dto.setIsSell("1");// 已回销
				int count = compensatoryMapper.updateById(dto);
				if (count < 1) {
					throw new MarvelsBusinessException("持久化回销状态异常");
				}
			}
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error(">>>>>loanId:" + loanId + ",回销异常:", e);
			throw new MarvelsBusinessException(e.getMessage());
		} finally {
			if (!CacheUtils.isNotLock(key, loanId)) {// 如果是锁住的将所释放
				CacheUtils.del(key);
			}
		}
	}

	/**
	 * 展期回销
	 * @param loanId
	 * @param extensionDay  展期天数
	 * @throws MarvelsBusinessException
	 */
	private void sellBackExtension(String loanId,int extensionDay,BigDecimal amount,long compensatoryId) throws MarvelsBusinessException{
		//查询进件状态  如果进件状态已还完 或者已结清则不能回销
		McfeCustomerLoanContractDTO loanContractDTO = mcfeCustomerLoanContractDao.selectContractByLoanId(loanId);
		int status=loanContractDTO.getStatus();
		if(status==2 || status==3 || status==10 ){//2结清 3提前结清 10核销
			throw new MarvelsBusinessException("进件当前状态不允许回销");
		}
		McfeLendingProcess mcfeLendingProcess=mcfeLendingProcessDao.selectByloanIdAndStatus(loanId, "");
		if(mcfeLendingProcess==null){
			throw new MarvelsBusinessException("放款信息不存在");
		}
		String extensionApr="";
		BigDecimal  principalAmtAct=mcfeLendingProcess.getPrincipalAmtAct();
		ExtensionFunctionEnum[] extensionlist=ExtensionFunctionEnum.enums();
		for(ExtensionFunctionEnum extensionFunctionEnum:extensionlist){
			if(extensionFunctionEnum.getDay()==extensionDay){//展期天数一致
				extensionApr=extensionFunctionEnum.getValue();
			}
		}
		BigDecimal extensionAmount=new BigDecimal(extensionApr).multiply(principalAmtAct);//除了滞纳金的展期金额
		if(amount.compareTo(extensionAmount)==-1){
			throw new MarvelsBusinessException("展期金额计算异常");
		}
		BigDecimal lateFee=amount.subtract(extensionAmount);//之前平掉的滞纳金

		//展期费回平账
		extensionFlatAccount(loanContractDTO,lateFee,extensionDay,compensatoryId);
	}



	/**
	 * 展期费回平账
	 * @param loanId
	 * @param amount
	 * @param extensionDay
	 * @throws MarvelsBusinessException
	 */
	private void extensionFlatAccount(McfeCustomerLoanContractDTO contractDTO ,BigDecimal lateFee,int extensionDay,long compensatoryId) throws MarvelsBusinessException{
		String loanId=contractDTO.getLoanId();
		Calendar calendar=Calendar.getInstance();
		//查询还款计划
		List<McfeCustomerRepaymentPlanDTO> planList=mcfeCustomerRepaymentPlanDao.selectAllPlan(loanId);
		if(planList==null || planList.size()<1){
			throw new MarvelsBusinessException("还款计划不存在");
		}
		McfeCustomerRepaymentPlanDTO planDTO=planList.get(0);//只有一条还款计划
		// 保存客户还款计划回销记录表
		long sellId=insertPlanSell(null,planDTO);
		calendar.setTime(planDTO.getPaymentDateLate());
		int actDay=0;
		if(extensionDay!=1){//展期天数为1天则不包含今天  展期天数不为1需要包含今天
			actDay=extensionDay-1;
		}else{
			actDay=extensionDay;
		}
		calendar.add(Calendar.DAY_OF_YEAR, -actDay);
		Date paymentDateLate=calendar.getTime();
		Integer delqDays=0;
		//判断之前是逾期还是正常的
		if(lateFee.compareTo(BigDecimal.ZERO)==1){//逾期
			//查询逾期记录表的逾期天数
			delqDays=overDueManageMapper.selectByPlanCode(planDTO.getPlanCode(), lateFee);
			if(delqDays==null){
				throw new MarvelsBusinessException("查询逾期天数异常");
			}
			//计算逾期天数
			calendar.add(Calendar.DAY_OF_YEAR, -delqDays);
			paymentDateLate=calendar.getTime();
		}
		//更新合同计划的最迟还款日
		UserDTO user = null;
		try {
			user=CacheUtils.getCacheUser();
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error(">>>>获取本地用户信息失败");
		}
		String userCode=user==null?"system":user.getUserCode();
		planDTO.setUpdatedBy(userCode);
		planDTO.setDelqDays(delqDays);
		planDTO.setStatus(delqDays>0?1:0);
		//设置还款计划剩余应还滞纳金信息
		planDTO.setLateFee(lateFee);
		//设置还款计划已还滞纳金信息
		planDTO.setLateFeeAct(planDTO.getLateFeeAct().subtract(lateFee));
		planDTO.setUpdatedDate(new Date());
		planDTO.setPaymentDateLate(paymentDateLate);
		mcfeCustomerRepaymentPlanDao.updateRepaymentPlanById2(planDTO);
		//保存回销之后的还款计划
		McfeCustomerRepaymentPlanSell planSellDTO=new McfeCustomerRepaymentPlanSell();
		planSellDTO.setSellType("2");
		planSellDTO.setLastRecordId(sellId);
		planSellDTO.setCompensatoryId(compensatoryId);
		insertPlanSell(planSellDTO,mcfeCustomerRepaymentPlanDao.selectAllPlan(loanId).get(0));
		//修改合同表状态和逾期天数
		McfeCustomerLoanContractDTO mcfeCustomerLoanContractDTO=new McfeCustomerLoanContractDTO();
		mcfeCustomerLoanContractDTO.setLoanId(loanId);
		mcfeCustomerLoanContractDTO.setDelqDays(delqDays);
		mcfeCustomerLoanContractDTO.setStatus(delqDays>0?1:0);//正常
		//保存客户贷款合同回销记录
		long contractSellId=insertContractSell(null,contractDTO);
		//设置合同已还滞纳金信息
		mcfeCustomerLoanContractDTO.setLateFee(contractDTO.getLateFee().subtract(lateFee));
		//设置合同剩余应还滞纳金信息
		mcfeCustomerLoanContractDTO.setLateFeeOs(contractDTO.getLateFeeOs().add(lateFee));
		mcfeCustomerLoanContractDTO.setId(contractDTO.getId());
		mcfeCustomerLoanContractDTO.setUpdatedDate(new Date());
		mcfeCustomerLoanContractDTO.setUpdatedBy(userCode);
		mcfeCustomerLoanContractDao.updateContractStatusByLoanId(mcfeCustomerLoanContractDTO);
		//保存回销后的客户贷款合同回销记录
		McfeCustomerLoanContractSell contractSellDTO=new McfeCustomerLoanContractSell();
		contractSellDTO.setSellType("2");
		contractSellDTO.setLastRecordId(contractSellId);
		contractSellDTO.setCompensatoryId(compensatoryId);
		insertContractSell(contractSellDTO,mcfeCustomerLoanContractDao.selectContractByLoanId(loanId));
	}


	/**
	 * 还款回退
	 * @param compensatoryDto
	 */
	private void sellBackPayment(McfeWithholdCompensatoryDto compensatoryDto,long compensatoryId) throws MarvelsBusinessException{
		String transctionSeq=compensatoryDto.getTransctionSeq();
		//根据请求编号查询冲账记录
		List<McfeReversalFlowDTO> list=reversalFlowDao.selectReversalFlow(transctionSeq);
//		LendPaymentConditionDTO lendPaymentConditionDTO = new LendPaymentConditionDTO();
//		List<McfeRepaymentFlowDTO> list = repaymentFlowDao.selectRepaymentFlowList( lendPaymentConditionDTO);
		if(CollectionUtils.isEmpty(list)){
			throw new MarvelsBusinessException("无还款计划冲销记录");
		}
		for(McfeReversalFlowDTO dto:list){//遍历冲销记录
			String planCode=dto.getPlanCode();
			//查询planCode对应的还款计划
			McfeCustomerRepaymentPlanDTO planDTO=planDao.selectPlanByPlanCode(planCode);
			// 保存客户还款计划回销记录表
			long sellId=insertPlanSell(null,planDTO);
			BigDecimal adjustPrincipalAct=dto.getPrincipalAct()==null?BigDecimal.ZERO:dto.getPrincipalAct();
			BigDecimal adjustInterestAct=dto.getInterestAct()==null?BigDecimal.ZERO:dto.getInterestAct();
			BigDecimal adjustConsultingFeeAct=dto.getConsultingFeeAct()==null?BigDecimal.ZERO:dto.getConsultingFeeAct();
			BigDecimal adjustManagementFeeAct=dto.getManagementFeeAct()==null?BigDecimal.ZERO:dto.getManagementFeeAct();
			BigDecimal adjustPenaltyFeeAct=dto.getPenaltyFeeAct()==null?BigDecimal.ZERO:dto.getPenaltyFeeAct();
			BigDecimal adjustLateFeeAct=dto.getLateFeeAct()==null?BigDecimal.ZERO:dto.getLateFeeAct();
			BigDecimal adjustPreTerminateFeeAct =dto.getPreTerminateFeeAct()==null?BigDecimal.ZERO:dto.getPreTerminateFeeAct();
			BigDecimal adjustMiscFeeAct=dto.getMiscFeeAct()==null?BigDecimal.ZERO:dto.getMiscFeeAct();
			BigDecimal adjustPlatformFeeAct=dto.getPlatformFeeAct()==null?BigDecimal.ZERO:dto.getPlatformFeeAct();
			BigDecimal adjustRiskFeeAct=dto.getRiskFeeAct()==null?BigDecimal.ZERO:dto.getRiskFeeAct();
			planDTO.setPrincipalAct(planDTO.getPrincipalAct().subtract(adjustPrincipalAct));
			planDTO.setInterestAct(planDTO.getInterestAct().subtract(adjustInterestAct));
			planDTO.setConsultingFeeAct(planDTO.getConsultingFeeAct().subtract(adjustConsultingFeeAct));
			planDTO.setManagementFeeAct(planDTO.getManagementFeeAct().subtract(adjustManagementFeeAct));
			planDTO.setPenaltyFeeAct(planDTO.getPenaltyFeeAct().subtract(adjustPenaltyFeeAct));
			planDTO.setLateFeeAct(planDTO.getLateFeeAct().subtract(adjustLateFeeAct));
			planDTO.setPreTerminateFeeAct(planDTO.getPreTerminateFeeAct().subtract(adjustPreTerminateFeeAct));
			planDTO.setMiscFeeAct(planDTO.getMiscFeeAct().subtract(adjustMiscFeeAct));
			planDTO.setPlatformFeeAct(planDTO.getPlatformFeeAct().subtract(adjustPlatformFeeAct));
			planDTO.setRiskFeeAct(planDTO.getRiskFeeAct().subtract(adjustRiskFeeAct));
			Date paymentDateAct=planDTO.getPaymentDateAct();
			Date paymentDateLate=planDTO.getPaymentDateLate();
			int status=planDTO.getStatus();//0正常 1逾期 2结清 3提前结清 10核销
			if(paymentDateAct!=null){//已还款
				if(paymentDateAct.after(paymentDateLate)){//逾期
					planDTO.setStatus(1);
					int dateDiff=DateUtils.diffTowDate(paymentDateLate,new Date());
					planDTO.setDelqDays(dateDiff);
				}else {
					if(status==2 || status==3){
						planDTO.setStatus(0);
					}
				}
				planDTO.setPaymentDateAct(null);
			}
			UserDTO user=CacheUtils.getCacheUser();
			planDTO.setUpdatedBy(user.getUserCode());
			planDTO.setUpdatedDate(new Date());
			mcfeCustomerRepaymentPlanDao.updateRepaymentPlanById2(planDTO);
			//保存回销之后的还款计划
			McfeCustomerRepaymentPlanSell planSellDTO=new McfeCustomerRepaymentPlanSell();
			planSellDTO.setSellType("1");
			planSellDTO.setLastRecordId(sellId);
			planSellDTO.setCompensatoryId(compensatoryId);
			insertPlanSell(planSellDTO,planDTO);
			//更新合同
			Map<String,BigDecimal> map =new HashMap<String,BigDecimal>();
			map.put("principal", adjustPrincipalAct);
			map.put("interest", adjustInterestAct);
			map.put("consultingFee",adjustConsultingFeeAct);
			map.put("managementFee",adjustManagementFeeAct);
			map.put("penaltyFee",adjustPenaltyFeeAct);
			map.put("lateFee", adjustLateFeeAct);
			map.put("preTerminateFee",adjustPreTerminateFeeAct);
			map.put("miscFee", adjustMiscFeeAct);
			map.put("platformFee", adjustRiskFeeAct);
			sellBackContract(planDTO,map,compensatoryId);//回销合同
		}

	}


	/**
	 * 合同回销
	 * @param plan
	 * @param map
	 * @throws MarvelsBusinessException
	 */
	private void sellBackContract(McfeCustomerRepaymentPlanDTO plan,Map<String,BigDecimal> map,long compensatoryId) throws MarvelsBusinessException{
		McfeCustomerLoanContractDTO contract=mcfeCustomerLoanContractDao.selectContractByLoanId(plan.getLoanId());
		//保存客户贷款合同回销记录
		long contractSellId=insertContractSell(null,contract);
		Set<String> set = map.keySet();
		for(String fieldCode:set){
			if("principal".equals(fieldCode)){
				contract.setPrincipal(contract.getPrincipal().subtract(map.get(fieldCode)));
				contract.setPrincipalOs(contract.getPrincipalOs().add(map.get(fieldCode)));
        	}else if("interest".equals(fieldCode)){
        		contract.setInterest(contract.getInterest().subtract(map.get(fieldCode)));
        		contract.setInterestOs(contract.getInterestOs().add(map.get(fieldCode)));
        	}else if("consultingFee".equals(fieldCode)){
        		contract.setConsultingFee(contract.getConsultingFee().subtract(map.get(fieldCode)));
        		contract.setConsultingFeeOs(contract.getConsultingFeeOs().add(map.get(fieldCode)));
        	}else if("managementFee".equals(fieldCode)){
        		contract.setManagementFee(contract.getManagementFee().subtract(map.get(fieldCode)));
        		contract.setManagementFeeOs(contract.getManagementFeeOs().add(map.get(fieldCode)));
        	}else if("penaltyFee".equals(fieldCode)){
        		contract.setPenaltyFee(contract.getPenaltyFee().subtract(map.get(fieldCode)));
        		contract.setPenaltyFeeOs(contract.getPenaltyFeeOs().add(map.get(fieldCode)));
        	}else if("lateFee".equals(fieldCode)){
        		contract.setLateFee(contract.getLateFee().subtract(map.get(fieldCode)));
        		contract.setLateFeeOs(contract.getLateFeeOs().add(map.get(fieldCode)));
        	}else if("preTerminateFee".equals(fieldCode)){
        		contract.setPreTerminateFee(contract.getPreTerminateFee().subtract(map.get(fieldCode)));
        		contract.setPreTerminateFeeOs(contract.getPreTerminateFeeOs().add(map.get(fieldCode)));
        	}else if("miscFee".equals(fieldCode)){
        		contract.setMiscFee(contract.getMiscFee().subtract(map.get(fieldCode)));
        		contract.setMiscFeeOs(contract.getMiscFeeOs().add(map.get(fieldCode)));
        	}else if("platformFee".equals(fieldCode)){
        		contract.setPlatformFee(contract.getPlatformFee().subtract(map.get(fieldCode)));
        		contract.setPlatformFeeOs(contract.getPlatformFeeOs().add(map.get(fieldCode)));
        	}
		}
        List<McfeCustomerRepaymentPlanDTO> list = mcfeCustomerRepaymentPlanDao.selectAllUncompletedPlan(plan.getLoanId());
        Integer delqDays = 0;
        for (McfeCustomerRepaymentPlanDTO mppi :list){
            if (1==mppi.getStatus() && mppi.getDelqDays()>delqDays){//循环还款计划取出最大的逾期天数
                delqDays=mppi.getDelqDays();
            }
        }
        if(delqDays.intValue() > 0) {
        	contract.setStatus(MarvelsConstant.CONTRACT_ACCOUNT_STATUS_DELQ);
        	contract.setDelqDays(delqDays);
        } else {
        	contract.setStatus(MarvelsConstant.CONTRACT_ACCOUNT_STATUS_NORMAL);
        	contract.setDelqDays(0);
        	contract.setForceFlag(MarvelsConstant.FORCE_COLLECTION_FLAG_A0);
        }
        contract.setCurrTenor(plan.getTenor());
        UserDTO user=CacheUtils.getCacheUser();
        contract.setUpdatedBy(user.getUserCode());
        contract.setUpdatedDate(new Date());
        mcfeCustomerLoanContractDao.updateContractInfoByLoanId2(contract);

        //保存回销后的客户贷款合同回销记录
		McfeCustomerLoanContractSell contractSellDTO=new McfeCustomerLoanContractSell();
		contractSellDTO.setSellType("2");
		contractSellDTO.setLastRecordId(contractSellId);
		contractSellDTO.setCompensatoryId(compensatoryId);

		//修改进件表中的实际放款金额
		com.marvels.approve.loan.dto.McamLoanApplyInfoDTO mcamLoanApplyInfoDTO=new com.marvels.approve.loan.dto.McamLoanApplyInfoDTO();
		mcamLoanApplyInfoDTO.setLoanId(plan.getLoanId());
		mcamLoanApplyInfoDTO.setUpdatedBy(user.getUserCode());
		mcamLoanApplyInfoDTO.setUpdatedDate(new Date());
		mcamLoanApplyInfoDTO.setStatus(LoanStateConstant.D01);
		iMcamLoanApplyInfoDao.updateByLoanId(mcamLoanApplyInfoDTO);

		//修改ac_loan表中的时间放款金额
		AcLoanApplyInfoDTO acLoanApplyInfoDTO=new AcLoanApplyInfoDTO();
		acLoanApplyInfoDTO.setUpdateTime(new Date());
		acLoanApplyInfoDTO.setLoanId(plan.getLoanId());
		acLoanApplyInfoDTO.setStatus(LoanStateConstant.D01);
		acLoanApplyInfoDao.modifyAcLoanApplyInfo(acLoanApplyInfoDTO);
		insertContractSell(contractSellDTO,contract);
	}

	/**
	 * 保存客户还款计划回销记录表
	 * @param planSell
	 * @param plan
	 * @return
	 */
	private long insertPlanSell(McfeCustomerRepaymentPlanSell planSell,McfeCustomerRepaymentPlanDTO plan){
		if(planSell==null){
			planSell=new McfeCustomerRepaymentPlanSell();
		}
		planSell.setCustCardNo(plan.getCustCardNo());
		planSell.setCustName(plan.getCustName());
		planSell.setLoanId(plan.getLoanId());
		planSell.setPlanCode(plan.getPlanCode());
		planSell.setStatus(plan.getStatus());
		planSell.setTenor(plan.getTenor());
		planSell.setPaymentDate(plan.getPaymentDate());
		planSell.setPaymentDateAct(plan.getPaymentDateAct());
		planSell.setPaymentDateLate(plan.getPaymentDateLate());
		planSell.setDelqDays(plan.getDelqDays());
		planSell.setProductType(plan.getProductType());
		planSell.setProductTypeName(plan.getProductTypeName());
		planSell.setProductCode(plan.getProductCode());
		planSell.setProductName(plan.getProductName());
		planSell.setChannelCode(plan.getChannelCode());
		planSell.setChannelName(plan.getChannelName());
		planSell.setRepaymentType(plan.getRepaymentType());
		planSell.setPrincipal(plan.getPrincipal());
		planSell.setInterest(plan.getInterest());
		planSell.setConsultingFee(plan.getConsultingFee());
		planSell.setManagementFee(plan.getManagementFee());
		planSell.setPenaltyFee(plan.getPenaltyFee());
		planSell.setLateFee(plan.getLateFee());
		planSell.setPreTerminateFee(plan.getPreTerminateFee());
		planSell.setMiscFee(plan.getMiscFee());
		planSell.setPlatformFee(plan.getPlatformFee());
		planSell.setRiskFee(plan.getRiskFee());
		planSell.setPrincipalAct(plan.getPrincipalAct());
		planSell.setInterestAct(plan.getInterestAct());
		planSell.setConsultingFeeAct(plan.getConsultingFeeAct());
		planSell.setManagementFeeAct(plan.getManagementFeeAct());
		planSell.setPenaltyFeeAct(plan.getPenaltyFeeAct());
		planSell.setLateFeeAct(plan.getLateFeeAct());
		planSell.setPreTerminateFeeAct(plan.getPreTerminateFeeAct());
		planSell.setMiscFeeAct(plan.getMiscFeeAct());
		planSell.setPlatformFeeAct(plan.getPlatformFeeAct());
		planSell.setRiskFeeAct(plan.getRiskFeeAct());
		planSell.setPrincipalWaive(plan.getPrincipalWaive());
		planSell.setInterestWaive(plan.getInterestWaive());
		planSell.setConsultingFeeWaive(plan.getConsultingFeeWaive());
		planSell.setManagementFeeWaive(plan.getManagementFeeWaive());
		planSell.setPenaltyFeeWaive(plan.getPenaltyFeeWaive());
		planSell.setLateFeeWaive(plan.getLateFeeWaive());
		planSell.setPreTerminateFeeWaive(plan.getPreTerminateFeeWaive());
		planSell.setMiscFeeWaive(plan.getMiscFeeWaive());
		planSell.setPlatformFeeWaive(plan.getPlatformFeeWaive());
		planSell.setRiskFeeWaive(plan.getRiskFeeWaive());
		planSell.setFundCode(plan.getFundCode());
		planSell.setFundName(plan.getFundName());
		planSell.setFundPrincipal(plan.getFundPrincipal());
		planSell.setFundInterest(plan.getFundInterest());
		planSell.setFundConsultingFee(plan.getFundConsultingFee());
		planSell.setFundManagementFee(plan.getFundManagementFee());
		planSell.setFundPenaltyFee(plan.getFundPenaltyFee());
		planSell.setFundLateFee(plan.getFundLateFee());
		planSell.setFundPreTerminateFee(plan.getFundPreTerminateFee());
		planSell.setFundMiscFee(plan.getFundMiscFee());
		planSell.setFundPlatformFee(plan.getFundPlatformFee());
		planSell.setFundRiskFee(plan.getFundRiskFee());
		planSell.setFundPrincipalAct(plan.getFundPrincipalAct());
		planSell.setFundInterestAct(plan.getFundInterestAct());
		planSell.setFundConsultingFeeAct(plan.getFundConsultingFeeAct());
		planSell.setFundManagementFeeAct(plan.getFundManagementFeeAct());
		planSell.setFundPenaltyFeeAct(plan.getFundPenaltyFeeAct());
		planSell.setFundLateFeeAct(plan.getFundLateFeeAct());
		planSell.setFundPreTerminateFeeAct(plan.getFundPreTerminateFeeAct());
		planSell.setFundMiscFeeAct(plan.getFundMiscFeeAct());
		planSell.setFundPlatformFeeAct(plan.getFundPlatformFeeAct());
		planSell.setFundRiskFeeAct(plan.getFundRiskFeeAct());
		planSell.setFundPrincipalWaive(plan.getFundPrincipalWaive());
		planSell.setFundInterestWaive(plan.getFundInterestWaive());
		planSell.setFundConsultingFeeWaive(plan.getFundConsultingFeeWaive());
		planSell.setFundManagementFeeWaive(plan.getFundManagementFeeWaive());
		planSell.setFundPenaltyFeeWaive(plan.getFundPenaltyFeeWaive());
		planSell.setFundLateFeeWaive(plan.getFundLateFeeWaive());
		planSell.setFundPreTerminateFeeWaive(plan.getFundPreTerminateFeeWaive());
		planSell.setFundMiscFeeWaive(plan.getFundMiscFeeWaive());
		planSell.setFundPlatformFeeWaive(plan.getFundPlatformFeeWaive());
		planSell.setFundRiskFeeWaive(plan.getFundRiskFeeWaive());
		//先将未冲销之前的还款计划保存到冲销记录表中
		UserDTO user = null;
		try {
			user=CacheUtils.getCacheUser();
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error(">>>>获取本地用户信息失败");
		}
		String userCode=user==null?"system":user.getUserCode();
		planSell.setCreatedBy(userCode);
		planSell.setCreatedDate(new Date());
		planSell.setUpdatedBy(userCode);
		planSell.setUpdatedDate(new Date());
		mcfeCustomerRepaymentPlanSellMapper.insertSelective(planSell);
		return planSell.getId();
	}


	/**
	 * 保存客户贷款合同回销记录
	 * @param contractSell
	 * @param contractDTO
	 * @return
	 */
	private long insertContractSell(McfeCustomerLoanContractSell contractSell,McfeCustomerLoanContractDTO contractDTO){
		if(contractSell==null){
			contractSell=new McfeCustomerLoanContractSell();
		}
		contractSell.setCustCardNo(contractDTO.getCustCardNo());
		contractSell.setCustName(contractDTO.getCustName());
		contractSell.setMobile(contractDTO.getMobile());
		contractSell.setLoanId(contractDTO.getLoanId());
		contractSell.setStatus(contractDTO.getStatus());
		contractSell.setPaymentBankBranch(contractDTO.getPaymentBankBranch());
		contractSell.setPaymentBankName(contractDTO.getPaymentBankName());
		contractSell.setPaymentAcctName(contractDTO.getPaymentAcctName());
		contractSell.setPaymentAcctNo(contractDTO.getPaymentAcctNo());
		contractSell.setPaymentBankHead(contractDTO.getPaymentBankHead());
		contractSell.setDelqDays(contractDTO.getDelqDays());
		contractSell.setDelqDaysHis(contractDTO.getDelqDaysHis());
		contractSell.setDelqDaysMax(contractDTO.getDelqDaysMax());
		contractSell.setForceFlag(contractDTO.getForceFlag());
		contractSell.setForceReason(contractDTO.getForceReason());
		contractSell.setProductType(contractDTO.getProductType());
		contractSell.setProductTypeName(contractDTO.getProductTypeName());
		contractSell.setProductCode(contractDTO.getProductCode());
		contractSell.setProductName(contractDTO.getProductName());
		contractSell.setProductGroup(contractDTO.getProductGroup());
		contractSell.setPatternType(contractDTO.getPatternType());
		contractSell.setChannelCode(contractDTO.getChannelCode());
		contractSell.setChannelName(contractDTO.getChannelName());
		contractSell.setTenor(contractDTO.getTenor());
		contractSell.setCurrTenor(contractDTO.getCurrTenor());
		contractSell.setApplyTime(contractDTO.getApplyTime());
		contractSell.setStartDate(contractDTO.getStartDate());
		contractSell.setEndDate(contractDTO.getEndDate());
		contractSell.setFirstPaymentDate(contractDTO.getFirstPaymentDate());
		contractSell.setFirstPaymentAmount(contractDTO.getFirstPaymentAmount());
		contractSell.setLastPaymentDate(contractDTO.getLastPaymentDate());
		contractSell.setLastPaymentAmount(contractDTO.getLastPaymentAmount());
		contractSell.setAmount(contractDTO.getAmount());
		contractSell.setPrincipal(contractDTO.getPrincipal());
		contractSell.setInterest(contractDTO.getInterest());
		contractSell.setConsultingFee(contractDTO.getConsultingFee());
		contractSell.setManagementFee(contractDTO.getManagementFee());
		contractSell.setPenaltyFee(contractDTO.getPenaltyFee());
		contractSell.setLateFee(contractDTO.getLateFee());
		contractSell.setPreTerminateFee(contractDTO.getPreTerminateFee());
		contractSell.setMiscFee(contractDTO.getMiscFee());
		contractSell.setPlatformFee(contractDTO.getPlatformFee());
		contractSell.setRiskFee(contractDTO.getRiskFee());
		contractSell.setPrincipalOs(contractDTO.getPrincipalOs());
		contractSell.setInterestOs(contractDTO.getInterestOs());
		contractSell.setConsultingFeeOs(contractDTO.getConsultingFeeOs());
		contractSell.setManagementFeeOs(contractDTO.getManagementFeeOs());
		contractSell.setPenaltyFeeOs(contractDTO.getPenaltyFeeOs());
		contractSell.setLateFeeOs(contractDTO.getLateFeeOs());
		contractSell.setPreTerminateFeeOs(contractDTO.getPreTerminateFeeOs());
		contractSell.setMiscFeeOs(contractDTO.getMiscFeeOs());
		contractSell.setPlatformFeeOs(contractDTO.getPlatformFeeOs());
		contractSell.setRiskFeeOs(contractDTO.getRiskFeeOs());
		contractSell.setPrincipalWaive(contractDTO.getPrincipalWaive());
		contractSell.setInterestWaive(contractDTO.getInterestWaive());
		contractSell.setConsultingFeeWaive(contractDTO.getConsultingFeeWaive());
		contractSell.setManagementFeeWaive(contractDTO.getManagementFeeWaive());
		contractSell.setPenaltyFeeWaive(contractDTO.getPenaltyFeeWaive());
		contractSell.setLateFeeWaive(contractDTO.getLateFeeWaive());
		contractSell.setPreTerminateFeeWaive(contractDTO.getPreTerminateFeeWaive());
		contractSell.setMiscFeeWaive(contractDTO.getMiscFeeWaive());
		contractSell.setPlatformFeeWaive(contractDTO.getPlatformFeeWaive());
		contractSell.setRiskFeeWaive(contractDTO.getRiskFeeWaive());
		contractSell.setContractNo(contractDTO.getContractNo());
		contractSell.setFundCode(contractDTO.getFundCode());
		contractSell.setFundName(contractDTO.getFundName());
		contractSell.setFundPrincipal(contractDTO.getFundPrincipal());
		contractSell.setFundInterest(contractDTO.getFundInterest());
		contractSell.setFundConsultingFee(contractDTO.getFundConsultingFee());
		contractSell.setFundManagementFee(contractDTO.getFundManagementFee());
		contractSell.setFundPenaltyFee(contractDTO.getFundPenaltyFee());
		contractSell.setFundLateFee(contractDTO.getFundLateFee());
		contractSell.setFundPreTerminateFee(contractDTO.getFundPreTerminateFee());
		contractSell.setFundMiscFee(contractDTO.getFundMiscFee());
		contractSell.setFundPlatformFee(contractDTO.getFundPlatformFee());
		contractSell.setFundRiskFee(contractDTO.getFundRiskFee());
		contractSell.setFundPrincipalOs(contractDTO.getFundPrincipalOs());
		contractSell.setFundInterestOs(contractDTO.getFundInterestOs());
		contractSell.setFundConsultingFeeOs(contractDTO.getFundConsultingFeeOs());
		contractSell.setFundManagementFeeOs(contractDTO.getFundManagementFeeOs());
		contractSell.setFundPenaltyFeeOs(contractDTO.getFundPenaltyFeeOs());
		contractSell.setFundLateFeeOs(contractDTO.getFundLateFeeOs());
		contractSell.setFundPreTerminateFeeOs(contractDTO.getFundPreTerminateFeeOs());
		contractSell.setFundMiscFeeOs(contractDTO.getFundMiscFeeOs());
		contractSell.setFundPlatformFeeOs(contractDTO.getFundPlatformFeeOs());
		contractSell.setFundRiskFeeOs(contractDTO.getFundRiskFeeOs());
		contractSell.setFundPrincipalWaive(contractDTO.getFundPrincipalWaive());
		contractSell.setFundInterestWaive(contractDTO.getFundInterestWaive());
		contractSell.setFundConsultingFeeWaive(contractDTO.getFundConsultingFeeWaive());
		contractSell.setFundManagementFeeWaive(contractDTO.getFundManagementFeeWaive());
		contractSell.setFundPenaltyFeeWaive(contractDTO.getFundPenaltyFeeWaive());
		contractSell.setFundLateFeeWaive(contractDTO.getFundLateFeeWaive());
		contractSell.setFundPreTerminateFeeWaive(contractDTO.getFundPreTerminateFeeWaive());
		contractSell.setFundMiscFeeWaive(contractDTO.getFundMiscFeeWaive());
		contractSell.setFundPlatformFeeWaive(contractDTO.getFundPlatformFeeWaive());
		contractSell.setFundRiskFeeWaive(contractDTO.getFundRiskFeeWaive());
		UserDTO user = null;
		try {
			user=CacheUtils.getCacheUser();
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error(">>>>获取本地用户信息失败");
		}
		String userCode=user==null?"system":user.getUserCode();
		contractSell.setCreatedBy(userCode);
		contractSell.setCreatedDate(new Date());
		contractSell.setUpdatedBy(userCode);
		contractSell.setUpdatedDate(new Date());
		//先将未冲销之前的还款计划保存到冲销记录表中
		mcfeCustomerLoanContractSellMapper.insertSelective(contractSell);
		return contractSell.getId();
	}
}
